package com.wd.live.view.activity

import android.os.Build
import android.util.Log
import android.view.SurfaceView
import android.view.View
import androidx.annotation.RequiresApi
import androidx.lifecycle.Observer
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ToastUtils
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.wd.live.databinding.ActivityLookLiveBinding
import com.wd.live.model.SocketBean
import com.wd.live.model.base.BaseActivity
import com.wd.live.model.tool.BaseConstant
import com.wd.live.tool.socket.WebSocketUtils
import com.wd.live.view.custom.CustomDialog_four
import com.wd.live.view.custom.CustomDialog_gift_list
import com.wd.live.view.custom.Dispose
import com.wd.live.view.custom.longToast
import com.wd.live.viewmodel.OpenLiveViewModel

import io.agora.rtc2.ChannelMediaOptions
import io.agora.rtc2.Constants
import io.agora.rtc2.IRtcEngineEventHandler
import io.agora.rtc2.RtcEngine
import io.agora.rtc2.RtcEngineConfig
import io.agora.rtc2.video.VideoCanvas


//看播：
//


/**
 * 作者：马海钊
 * 时间：2023年8月19日11:21:31
 * 功能：看播
 */
//1、向服务端申请看播，想看谁直播，就把谁的liveId告诉服务器， 回调成功以后，
//返回几个参数，鉴权，liveid，频道名称
class LookLiveActivity : BaseActivity<OpenLiveViewModel, ActivityLookLiveBinding>() {

    private var remoteUid: Int = 0
    private var mRtcEngine: RtcEngine? = null
    override fun initData() {
        var liveid = intent.getIntExtra("liveid", 0)
        //连麦
        //1、请求服务器获取连麦请求
        //2、将local（楼口）数据开起来，本地摄像头啥的
        //3、角色发生变化
        //我们现在处于一个等待的状态中，等待主播同意
        XXPermissions.with(this).permission(Permission.RECORD_AUDIO, Permission.CAMERA)
            .request { permissions, all ->
                if (!all) {
                    longToast("获取部分权限成功，但部分权限未正常授予")
                }
                viewModel.looklive(liveid)
            }

        viewModel.lookLivevideoLiveData.observe(this, Observer {
            //TODD 改过 本来没有？
            if (it?.channelName != null && it?.liveId != null && it?.agoraToken != null) {
                initializeAndJoinChannel(it.agoraToken, it.channelName, it.liveId)
            }
            connectSocket(it?.compositeWsUrl!!)
        })
        //连麦
        binding.lookLianmai.setOnClickListener {
            viewModel.userlianmai(liveid)
            viewModel.UserShenQingLiveData.observe(this, Observer {
                ToastUtils.showLong(it.message)
            })
            var customdialogFour = CustomDialog_four(this)
            customdialogFour.show()
            binding.lookliveZhuboid.visibility = View.VISIBLE
            setupLocalVideo(1)
        }
        //送礼
        binding.lookGift.setOnClickListener {

            viewModel.queryGiftlist()

            viewModel.queryGiftLiveData.observe(this, Observer {
                val dialogGiftList = CustomDialog_gift_list(this, it, dispose = object : Dispose {
                    override fun giveGift(giftId: Int) {
                        if (giftId != null) {
                            viewModel.sendgift(giftId, liveid)
                        }
                    }
                })
                dialogGiftList.show()
            })
        }
        SVGAParser(this).decodeFromAssets("xin.svga", object : SVGAParser.ParseCompletion {
            @RequiresApi(api = Build.VERSION_CODES.P)
            override fun onComplete(videoItem: SVGAVideoEntity) {
                binding.mSVGAKninghtood.apply {
                    binding.mSVGAKninghtood.clear()
                    setVideoItem(videoItem)
                }
            }
            override fun onError() {}
        })
        viewModel.sendgiftLiveData.observe(this, Observer {
            if (it.status.equals("0000")){
                binding.mSVGAKninghtood.startAnimation()
            }
        })
    }

    private fun initializeAndJoinChannel(agoraToken: String, channelName: String, uid: Int) {
        try {
            val config = RtcEngineConfig()
            config.mContext = baseContext
            config.mAppId = BaseConstant.OPEN_LIVE_ID
            //2、对SDK初始化，  和开播一样，先注册一个eventHandler，我们SDK收到声网服
            //务器的状态，做下一步操作，
            //3、设置用户身份为观众
            config.mEventHandler = object : IRtcEngineEventHandler() {
                override fun onUserJoined(uid: Int, elapsed: Int) {
                    super.onUserJoined(uid, elapsed)
                    runOnUiThread {
                        longToast("主播加入成功")
                        remoteUid = uid
                        // 从 onUserJoined 回调获取 uid 后，调用 setupRemoteVideo，设置远端视频视图。
                        setupRemoteVideo(uid)
                    }
                }

                override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) {
                    super.onJoinChannelSuccess(channel, uid, elapsed)
                    runOnUiThread {
                        longToast("加入频道成功")
                    }
                }

                override fun onError(err: Int) {
                    Log.d("TAG", "onJoinChannelSuccess: $err")
                    super.onError(err)
                    runOnUiThread {
                        longToast("错误：$err")
                    }

                }
            }

            mRtcEngine = RtcEngine.create(config)?.apply {
                enableVideo()
                //设置成为观众
                setClientRole(Constants.CLIENT_ROLE_AUDIENCE)
                setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING)
                // 服务端接口返回的 token，channelName,以及我们的登陆信息userId
                val options = ChannelMediaOptions()
                options.autoSubscribeAudio = true
                options.autoSubscribeVideo = true
                joinChannel(agoraToken, channelName, BaseConstant.UID, options)
            }
        } catch (e: Exception) {
            throw RuntimeException("Check the error.")
        }
    }

    //4、加入频道，如果主播下线了，就是加入失败，如果加入成功，在eventHandler收
    //到加入频道成功，同时主播也会加入成功，（主播的数据流也会推到这个方法，通过这
    //个方法，会接收到这个状态） ，在这个方法里面把主播的信息画面展现出来
    private fun setupRemoteVideo(uid: Int) {

        val surfaceView = SurfaceView(baseContext)
        surfaceView.setZOrderMediaOverlay(true)
        binding.lookliveId.addView(surfaceView)
        mRtcEngine!!.setupRemoteVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid))
    }


    private fun setupLocalVideo(uid: Int) {
        binding.lookliveZhuboid.visibility = View.VISIBLE
        val surfaceView = SurfaceView(baseContext)
        surfaceView.setZOrderMediaOverlay(true)
        binding.lookliveZhuboid.addView(surfaceView)
        mRtcEngine?.setupLocalVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid))

        mRtcEngine?.setClientRole(Constants.CLIENT_ROLE_BROADCASTER)

    }

    private fun connectSocket(compositeWsUrl: String) {
        val webSocketUtils: WebSocketUtils = WebSocketUtils().startConnect(compositeWsUrl, this)
        webSocketUtils.setOnMessageListener(object : WebSocketUtils.OnMessageListener {
            override fun message(msg: String?) {
                if (msg != null) {
                    Log.d("connectSocket msg", msg.toString())
                    ToastUtils.showLong(msg.toString())
                    val socketBean = GsonUtils.fromJson(msg, SocketBean::class.java)
                    when (socketBean.msgType) {
                        101 -> {

                        }

                        102 -> {}
                        103 -> {}
                        104 -> {}
                    }
                }
            }
        })
    }
    //连麦：
//
//看播端：
//
//（详细）
//1、先在 看播端 调取申请连麦的接口，然后告诉服务端我们要对某个主播申请连麦，
//服务端再告诉声网，当这个请求成功返回以后（加入列表成功），对本地的视频流
//setUplocal，设置一下画面，给本地的数据做一个上传的准备，因为我们要连麦，
//所以要转换一下身份，把看播身份切换成主播
//
//（简要）

    override fun onDestroy() {
        super.onDestroy()
        mRtcEngine?.stopPreview()
        mRtcEngine?.leaveChannel()
    }

    override fun getViewBinding() = ActivityLookLiveBinding.inflate(layoutInflater)
}